php序列化与反序列化
serialize函数和unserialize函数
serialize()
该函数能将php已创建对象转变成字符串,使得该对象可以进行传递与使用
比如1
O:7:"chybeta":1:{s:4:"test";s:3:"123";}
这里的O代表存储的是对象(object),假如你给serialize()传入的是一个数组,那它会变成字母a。7表示对象的名称有7个字符。”chybeta”表示对象的名称。1表示有一个值。{s:4:”test”;s:3:”123”;}中,s表示字符串,4表示该字符串的长度,”test”为字符串的名称,之后的类似。
unserialize()
从序列化的结果中恢复对象,并调用_wakeup()成员函数
反序列化漏洞
反序列化数据本身没有危害,但我们可以通过传入一个精心构造的序列化字符串,从而控制对象内部的变量或者函数
Magic function
php有一类特殊的方法,被称之为魔术方法
- _construct():在new的时候会自动调用
- _destruct(): 在对象被销毁时自动调用
- _wakeup(): unserialize()时自动调用
1 | <?php |
由上述可知,unserialize()时会自动调用_wakeup()方法,在_wakeup()方法中,会打开shell.php,并往其中写入test变量的值,因此我们构造一个对象,将chybeta的test值修改为”<?php phpinfo(); ?>”,即可实现将shell.php的内容全部打印出来的功能。
绕过_wakeup()
有些时候类内部_destruct()存在漏洞,但_wakeup()会修改我们修改的变量,有点绕,总而言之我们必须绕过_wakeup()函数。
绕过方法:当序列化字符串中,表示对象属性个数的值大于实际属性个数时,那么就会跳过wakeup方法的执行。